package cn.songtx.iot.service.impl;

import cn.songtx.iot.mapper.DeviceEmMapper;
import cn.songtx.iot.pojo.DeviceEm;
import cn.songtx.iot.service.IDeviceEmService;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.*;

@Service
@DS("master")
public class DeviceEmServiceImpl extends ServiceImpl<DeviceEmMapper, DeviceEm> implements IDeviceEmService {

    @Autowired
    DeviceEmMapper deviceEmMapper;

    @Override
    public Map<String, float[]> selectPeakValleyElectricByMonth(String mac, String year, String month) {

        /*
          测试数据
        Map<String, float[]> map = new HashMap<>();
        map.put("2025-04-12", new float[]{22.1F, 11.4F, 33.5F});
        map.put("2025-04-13", new float[]{22.1F, 11.3F, 33.4F});
        map.put("2025-04-14", new float[]{22.1F, 11.2F, 33.3F});
         */

        // 1.查询全月有用的数据
        LambdaQueryWrapper<DeviceEm> wrapper = new LambdaQueryWrapper<>();
        LocalDate firstDay = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), 1); //获取当月第一天
        LocalDate lastDay = firstDay.withDayOfMonth(firstDay.lengthOfMonth());                            //获取当月最后一天

        // 构造查询条件
        wrapper.select(DeviceEm::getDatetime, DeviceEm::getElectricityConsumption) //只查询这两个字段
                .eq(DeviceEm::getMac, mac)                                         //匹配mac
                .orderByAsc(DeviceEm::getId);                                      //按照id升序排列
        for (LocalDate date = firstDay; !date.isAfter(lastDay); date = date.plusDays(1)) { //循环遍历当月的每天
            LocalDateTime startTime1 = LocalDateTime.of(date, LocalTime.of(0, 0, 0));
            LocalDateTime endTime1 = LocalDateTime.of(date, LocalTime.of(0, 1, 0));
            LocalDateTime startTime2 = LocalDateTime.of(date, LocalTime.of(8, 0, 1));
            LocalDateTime endTime2 = LocalDateTime.of(date, LocalTime.of(8, 1, 1));
            LocalDateTime startTime3 = LocalDateTime.of(date, LocalTime.of(22, 0, 1));
            LocalDateTime endTime3 = LocalDateTime.of(date, LocalTime.of(22, 1, 1));
            LocalDateTime startTime4 = LocalDateTime.of(date, LocalTime.of(23, 58, 59));
            LocalDateTime endTime4 = LocalDateTime.of(date, LocalTime.of(23, 59, 59));
            wrapper.between(DeviceEm::getDatetime, startTime1, endTime1).or().between(DeviceEm::getDatetime, startTime2, endTime2).or().between(DeviceEm::getDatetime, startTime3, endTime3).or().between(DeviceEm::getDatetime, startTime4, endTime4).or();
        }
        List<DeviceEm> deviceEms = deviceEmMapper.selectList(wrapper);

        // 2.电量数据转二位数组
        // 2.1 参数转年月格式
        YearMonth yearMonth = YearMonth.of(Integer.parseInt(year), Integer.parseInt(month));
        // 2.2 获取当月天数
        int today = yearMonth.lengthOfMonth();
        // 2.3 初始化返回数据 LinkedHashMap,按照日期时间存储
        float[][] fourElectric = new float[today][4];
        // 2.4 遍历数据,将数据存入 fourElectric 中
        for (DeviceEm deviceEm : deviceEms) {
            LocalDate date = LocalDate.from(deviceEm.getDatetime());
            LocalTime time = LocalTime.from(deviceEm.getDatetime());
            if (time.getHour() == 0 && deviceEm.getElectricityConsumption() != 0) {
                fourElectric[date.getDayOfMonth() - 1][0] = deviceEm.getElectricityConsumption();
            } else if (time.getHour() == 8 && deviceEm.getElectricityConsumption() != 0) {
                fourElectric[date.getDayOfMonth() - 1][1] = deviceEm.getElectricityConsumption();
            } else if (time.getHour() == 22 && deviceEm.getElectricityConsumption() != 0) {
                fourElectric[date.getDayOfMonth() - 1][2] = deviceEm.getElectricityConsumption();
            } else {
                fourElectric[date.getDayOfMonth() - 1][3] = deviceEm.getElectricityConsumption();
            }
        }
        // 2.4 打印测试
//        for (float[] floats : fourElectric) {
//            for (float aFloat : floats) {
//                System.out.print(aFloat + " ");
//            }
//            System.out.println();
//        }

        // 3.计算峰谷电,将数据存入map中
        Map<String, float[]> map = new LinkedHashMap<>();
        for (int i = 0; i < today; i++) {
            if (!(fourElectric[i][0] == 0 && fourElectric[i][1] == 0 && fourElectric[i][2] == 0 && fourElectric[i][3] == 0)) {
                float[] list = getPeakValleyList(fourElectric, i);
                map.put(firstDay.plusDays(i).toString(), list);
            }
        }
        return map;
    }

    /**
     * 获取峰谷电数据的方法,用4个时间点的数据计算
     *
     * @param fourElectric 4个电量数据,二位数组
     * @param i            日期
     * @return 峰谷电数据的list
     */
    private static float[] getPeakValleyList(float[][] fourElectric, int i) {
        float[] peakValleyElectric = new float[3];                   // 初始化峰谷电数据
        float valley1 = 0F;
        float valley2 = 0F;
        float peak = 0F;

        if (fourElectric[i][0] != 0 && fourElectric[i][1] != 0) {    // 谷电一
            valley1 = fourElectric[i][1] - fourElectric[i][0];       // 谷电一
        }
        if (fourElectric[i][2] != 0 && fourElectric[i][3] != 0) {    // 谷电二
            valley2 = fourElectric[i][3] - fourElectric[i][2];       // 谷电二
        }
        if (fourElectric[i][1] != 0 && fourElectric[i][2] != 0) {    // 峰电
            peak = fourElectric[i][2] - fourElectric[i][1];          // 峰电
        }

        DecimalFormat df = new DecimalFormat("#.00");        // 格式化数据,保留两位小数
        peakValleyElectric[0] = (Float.parseFloat(df.format(valley1 + valley2)));
        peakValleyElectric[1] = (Float.parseFloat(df.format(peak)));
        peakValleyElectric[2] = (Float.parseFloat(df.format(valley1 + valley2 + peak)));
        return peakValleyElectric;
    }

}
